local MINOR_VERSION = tonumber(("$Revision: 1 $"):match("%d+"))
if MINOR_VERSION > EQdkpRT.MINOR_VERSION then EQdkpRT.MINOR_VERSION = MINOR_VERSION end

local bars
local Attendees = EQdkpRT:NewModule("Attendees", EQdkpRT.ModuleBase, "AceEvent-3.0", "AceTimer-3.0")
local GUID = LibStub("LibGUIDRegistry-0.1")
local timers = {}
local table_sort = _G.table.sort
local math_abs = _G.math.abs
local OL = LibStub("AceLocale-3.0"):GetLocale("EQdkpRT")
local L = LibStub("AceLocale-3.0"):GetLocale("EQdkpRT_Attendees")
local GetTime = _G.GetTime

local showFocus, showTarget = false, false

local raidTargets, raidTargetsReverse = {}, {}
local playerGUID = UnitGUID("player")

local configOptions = {
	RaidIcons = true,
	ShowTarget = true,
	ShowFocus = true,
	Columns = {
		Name = true,
		Joined = true,
		Left = true
	}
}
local options = {
	type = "group",
	name = L["ModTitle"],
	desc = L["ModTitle"],
	args = {
		test = {
			type = "execute",
			name = OL["Show test bars"],
			desc = OL["Show test bars"],
			func = function() EQdkpRT:EnableModule("Attendees"); Attendees:Test() end
		},
		raidIcons = {
			type = "toggle",
			name = L["Show raid icons"],
			desc = L["Show raid icons"],
			get = function(info) return Attendees:GetOption("RaidIcons") end,
			set = function(info, v)
				Attendees:SetOption("RaidIcons", v)
				Attendees:ReleaseBars()
			end
		},
		showTarget = {
			type = "toggle",
			name = L["Indicate target"],
			desc = L["Indicate target"],
			get = function(info) return Attendees:GetOption("ShowTarget") end,
			set = function(info, v)
				Attendees:SetOption("ShowTarget", v)
				showTarget = v
			end
		},
		showFocus = {
			type = "toggle",
			name = L["Indicate focus"],
			desc = L["Indicate focus"],
			get = function(info) return Attendees:GetOption("ShowFocus") end,
			set = function(info, v)
				Attendees:SetOption("ShowFocus", v)
				showFocus = v
			end
		},
		columns = {
			type = "group",
			name = L["Columns"],
			desc = L["Select which columns to show"],
			args = {
				name = {
					type = "toggle",
					name = L["Name"],
					desc = L["Show the Name column"],
					get = function(info) return Attendees:GetOption("Columns.Name") end,
					set = function(info, v)
						Attendees:SetOption("Columns.Name", v)
						Attendees:UpdateBarLabels()
					end
				},
				tps = {
					type = "toggle",
					name = L["TPS"],
					desc = L["Show the TPS column"],
					get = function(info) return Attendees:GetOption("Columns.TPS") end,
					set = function(info, v)
						Attendees:SetOption("Columns.TPS", v)
						Attendees:UpdateBarLabels()
					end
				},
				tpqfreq = {
					type = "range",
					name = L["TPS Update Frequency"],
					desc = L["TPS Update Frequency"],
					min = 0.05,
					max = 5.0,
					step = 0.05,
					bigStep = 0.05,
					get = function(info) return Attendees:GetOption("TPS.UpdateFrequency") end,
					set = function(info, v)
						Attendees:SetOption("TPS.UpdateFrequency", v)
						Attendees:ReInitTPSTimer()
					end
				},
				threat = {
					type = "toggle",
					name = L["Threat"],
					desc = L["Show the Threat column"],
					get = function(info) return Attendees:GetOption("Columns.Threat") end,
					set = function(info, v)
						Attendees:SetOption("Columns.Threat", v)
						Attendees:UpdateBarLabels()
					end
				},
				pct = {
					type = "toggle",
					name = L["Percent"],
					desc = L["Show the Percent column"],
					get = function(info) return Attendees:GetOption("Columns.Percent") end,
					set = function(info, v)
						Attendees:SetOption("Columns.Percent", v)
						Attendees:UpdateBarLabels()
					end
				}
			}
		}
	}
}

local function sortBars(a, b)
	if a:GetValue() > b:GetValue() then
		return true
	end
	return false
end

function Attendees:OnInitialize()
	self:Super("OnInitialize")
	self.icon = select(3, GetSpellInfo(25429)) -- Fade
	self:RegisterConfigDefaults(configOptions)
	self:RegisterOptions(options)
end

function Attendees:Hint()
	return L["ModHint"]
end

function Attendees:UpdateLayout()
	self:ArrangeBars()
end

function Attendees:OnEnable()
	self:Super("OnEnable")
	bars = self.bars

	GUID.RegisterCallback(self, "RaidTargetGUIDSet")

	EQdkpRT:SetTitle(L["ModTitle"] .. ": " .. UnitName("player"))
--[[ geh
	for k, v in Threat:IteratePlayerThreat(playerGUID) do
		Attendees:UpdateBar(k, v)
	end	
]]	
	showFocus = self:GetOption("ShowFocus")
	showTarget = self:GetOption("ShowTarget")
end

function Attendees:OnDisable()
	self:Super("OnDisable")
	GUID.UnregisterCallback(self, "RaidTargetGUIDSet")
-- geh	Threat.UnregisterCallback(self, "ThreatUpdated")
end

function Attendees.RaidTargetGUIDSet(lib, guid, name, target, unitID)
	if raidTargetsReverse[target] then
		raidTargets[raidTargetsReverse[target]] = nil
	end
	raidTargets[guid] = target
	raidTargetsReverse[target] = guid
end

function Attendees:UpdateLayout()
	self:ArrangeBars()
end

local barOptions = {}
function Attendees:GetBarOptions()
	bars = self.bars
	local options = barOptions
	for i = 1, #options do
		tremove(options)
	end
	local used = 0
	if self:GetOption("Columns.Name") then
		tinsert(options, "Name")
		tinsert(options, "LEFT")
		tinsert(options, 40)
		used = used + 40
	end
	if self:GetOption("Columns.TPS") then
		tinsert(options, "TPS")
		tinsert(options, "LEFT")
		tinsert(options, 20)
		used = used + 20
	end
	if self:GetOption("Columns.Threat") then
		tinsert(options, "Threat")
		tinsert(options, "RIGHT")
		tinsert(options, 20)
		used = used + 20
	end
	if self:GetOption("Columns.Percent") then
		tinsert(options, "%")
		tinsert(options, "RIGHT")
		tinsert(options, 20)
		used = used + 20
	end
	for i = 3, #options, 3 do
		options[i] = options[i] * (100 / used)
	end
	return options
end

function Attendees:UpdateBarLabels()
	local options = self:GetBarOptions()
	for k, v in pairs(bars) do
		v:ClearLabels()
		v:SetLabels(unpack(options))
	end
end

local lastUpdatedAt = 0
function Attendees:UpdateBar(guid, threat, overrideMax)
	local bar, isNew = self:AcquireBar(guid)
	if isNew then
		bar:SetLabels( unpack(self:GetOption("RaidIcons") and labelsWithIcon or labelsNoIcon) )
		bar:SetLabel("Icon", nil)
		bar:SetLabel("Enemy", Threat.GUIDNameLookup[guid])
	end
-- geh	local pct = threat / (overrideMax or Threat:GetMaxThreatOnTarget(guid))
-- geh	bar:SetLabel("Threat", bar:ConvertToK(threat))
	bar:SetLabel("Threat")
	bar:SetValue(pct)
	if GetTime() - lastUpdatedAt > 0.25 then
		lastUpdatedAt = GetTime()
		self:ArrangeBars()
	end
end

function Attendees:ArrangeBars()
	self:ResetBars()
	table_sort(bars, sortBars)
	for i = 1, 80 do		-- A raid of 40 hunters!
		local bar = bars[i]
		if not bar then break end
		bar:SetLabel("Enemy", Threat.GUIDNameLookup[bar.guid])
		if showFocus and bar.guid == UnitGUID("focus") then
			bar:SetLabel("Enemy", "[F] " .. Threat.GUIDNameLookup[bar.guid])
		elseif showTarget and bar.guid == UnitGUID("target") then
			bar:SetLabel("Enemy", "[T] " .. Threat.GUIDNameLookup[bar.guid])
		end
		
		if raidTargets[bar.guid] and bar.hasIcon ~= raidTargets[bar.guid] then
			bar:SetLabel("Icon", raidTargets[bar.guid])
		end
		
		if bar:GetValue() > 0 and self:AddBar(bar) then
			local pct = bar:GetValue()
			local r, g, b
			if pct < 0.5 then
				g = 1
				r = (pct / 0.5)
			else
				r = 1
				g = 1 - ((pct - 0.5) / 0.5)
			end
			bar:SetColor(r, g, b)
			bar:SetPercent(pct)
			bar:SetLabel("%Max", ("%2.0f%%"):format(pct*100))
		else
			bar.frame:Hide()
		end
	end
end

function Attendees:Test()
	self.testing = true
	self:ReleaseBars()

	for i = 1, 25 do
		raidTargets[i] = mod(i, 8) + 1
		self:UpdateBar(i, i, 25)
	end
	self:ArrangeBars()
end
